﻿
// MFCApplication1View.cpp: CMFCApplication1View 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFCApplication1.h"
#endif

#include "MFCApplication1Doc.h"
#include "MFCApplication1View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMFCApplication1View

IMPLEMENT_DYNCREATE(CMFCApplication1View, CView)

BEGIN_MESSAGE_MAP(CMFCApplication1View, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_KEYDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_CHAR()
	ON_MESSAGE(WM_MY_MESSAGE, &CMFCApplication1View::OnMyMessage)
END_MESSAGE_MAP()

// CMFCApplication1View 构造/析构

CMFCApplication1View::CMFCApplication1View() noexcept
{
	// TODO: 在此处添加构造代码

}

CMFCApplication1View::~CMFCApplication1View()
{
}

BOOL CMFCApplication1View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CMFCApplication1View 绘图

void CMFCApplication1View::OnDraw(CDC* pDC)
{
	CMFCApplication1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	//在绘图界面显示提示消息
	pDC->TextOutW(200, 150, L"按键消息：");
	pDC->TextOutW(600, 150, L"自定义消息：");
}


// CMFCApplication1View 打印

BOOL CMFCApplication1View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CMFCApplication1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CMFCApplication1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// CMFCApplication1View 诊断

#ifdef _DEBUG
void CMFCApplication1View::AssertValid() const
{
	CView::AssertValid();
}

void CMFCApplication1View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMFCApplication1Doc* CMFCApplication1View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCApplication1Doc)));
	return (CMFCApplication1Doc*)m_pDocument;
}
#endif //_DEBUG


// CMFCApplication1View 消息处理程序


void CMFCApplication1View::OnLButtonDown(UINT nFlags, CPoint point)
{
	
	//获取hWnd所指窗口的客户区的设备环境
	CDC* pDC = GetDC();
	CString str;
	//判断点击左键时是否按下了CTRL，并使用format将格式字符转化为字符串
	if (MK_CONTROL & nFlags) {
		str.Format(TEXT("鼠标左键 + CTRL键，x = %d, y = %d"), point.x, point.y);
	}
	else {
		str.Format(TEXT("鼠标左键，x = %d, y = %d"), point.x, point.y);
	}
	//弹出消息对话框
	MessageBox(str);
	//释放设备上下文环境
	ReleaseDC(pDC);
	CView::OnLButtonDown(nFlags, point);
}




void CMFCApplication1View::clear(){
	//清屏函数，除提示消息外的所有消息都会被清空、置为初始状态
	CDC* pDC = GetDC();
	CRect rc;
	GetClientRect(&rc);
	//通过覆盖一个填充为白色的矩形实现
	pDC->FillSolidRect(&rc, RGB(255, 255, 255));
	//注意要恢复提示消息
	pDC->TextOutW(200, 150, L"按键消息：");
	pDC->TextOutW(600, 150, L"自定义消息："); 
	//释放设备上下文环境
	ReleaseDC(pDC);
}


void CMFCApplication1View::OnRButtonDown(UINT nFlags, CPoint point)
{
	//组合键清屏：SHIFT+鼠标右键实现清屏，调用clear（）函数

	//只有当控制键状态nFlags == SHIFT 时，按下鼠标右键才会触发清屏
	if (MK_SHIFT & nFlags) {
		clear();
	}
	CView::OnRButtonDown(nFlags, point);
}


void CMFCApplication1View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	//响应键盘字符消息
	//获取hWnd所指窗口的客户区的设备环境
	CDC* pDC = GetWindowDC();
	CString str;
	str.Format(TEXT("%c pressed"), nChar);
	//当键入字符nChar为字母或数字时在屏幕上打印，这样可以避免输入"SHIFT"等控制键出现乱码现象。而使用消息预处理PreTranslateMessage捕获控制键消息
	if ((nChar >= '0' && nChar <= '9') || (nChar >= 'a' && nChar <= 'z') || (nChar >= 'A' && nChar <= 'Z')) {
		//先清屏，避免长短字符串重叠
		clear();
		pDC->TextOutW(200, 200, str);
	}
	//释放设备上下文环境
	ReleaseDC(pDC);
	CView::OnChar(nChar, nRepCnt, nFlags);
}


BOOL CMFCApplication1View::PreTranslateMessage(MSG* pMsg)
{
	//响应非字符键消息
	//获取hWnd所指窗口的客户区的设备环境
	CDC* pDC = GetWindowDC();
	//使用消息指针获取当前消息，若是键盘消息，则进入switch语句进一步判断。这里对键盘上的按键都进行了显示
	if (pMsg->message == WM_KEYDOWN) {
		//在输出前先清屏，避免长短字符串重叠
		clear();
		switch (pMsg->wParam) {
			//输出@组合键的显示：在按下2时要判断SHIFT的状态
			//若按下，short类型的GetAsyncKeyState(VK_LSHIFT)的高位为1，使用0x8000与，捕获SHIFT是否被按下，若是，则sendMessage
		case '2':
			if (0x8000 & GetAsyncKeyState(VK_LSHIFT))
				SendMessage(WM_MY_MESSAGE,10,50);
			break;
		case VK_F1:
			pDC->TextOutW(200,200,L"F1 pressed!");
			break;
		case VK_F2:
			pDC->TextOutW(200, 200, L"F2 pressed!");
			break;
		case VK_F3:
			pDC->TextOutW(200, 200, L"F3 pressed!");
			break;
		case VK_F4:
			pDC->TextOutW(200, 200, L"F4 pressed!");
			break;
		case VK_F5:
			pDC->TextOutW(200, 200, L"F5 pressed!");
			break;
		case VK_F6:
			pDC->TextOutW(200, 200, L"F6 pressed!");
			break;
		case VK_F7:
			pDC->TextOutW(200, 200, L"F7 pressed!");
			break;
		case VK_F8:
			pDC->TextOutW(200, 200, L"F8 pressed!");
			break;
		case VK_F9:
			pDC->TextOutW(200, 200, L"F9 pressed!");
			break;
		case VK_F10:
			pDC->TextOutW(200, 200, L"F10 pressed!");
			break;
		case VK_F11:
			pDC->TextOutW(200, 200, L"F11 pressed!");
			break;
		case VK_F12:
			pDC->TextOutW(200, 200, L"F12 pressed!");
			break;
		case VK_ESCAPE:
			pDC->TextOutW(200, 200, L"ESC pressed!");
			break;
		case VK_RETURN:
			pDC->TextOutW(200, 200, L"RETURN pressed!");
			break;
		case VK_TAB:
			pDC->TextOutW(200, 200, L"TAB pressed!");
			break;
		case VK_CAPITAL:
			pDC->TextOutW(200, 200, L"CAPITAL pressed!");
			break;
		case VK_SHIFT:
			pDC->TextOutW(200, 200, L"SHIFT pressed!");
			break;
		case VK_CONTROL:
			pDC->TextOutW(200, 200, L"CONTROL pressed!");
			break;
		case VK_MENU:
			pDC->TextOutW(200, 200, L"ALT pressed!");
			break;
		case VK_SPACE:
			pDC->TextOutW(200, 200, L"SPACE pressed!");
			break;
		case VK_BACK:
			pDC->TextOutW(200, 200, L"BACK pressed!");
			break;
		case VK_INSERT:
			pDC->TextOutW(200, 200, L"INSERT pressed!");
			break;
		case VK_HOME:
			pDC->TextOutW(200, 200, L"HOME pressed!");
			break;
		case VK_PRIOR:
			pDC->TextOutW(200, 200, L"PAGE UP pressed!");
			break;
		case VK_NEXT:
			pDC->TextOutW(200, 200, L"PAGE DOWN pressed!");
			break;
		case VK_END:
			pDC->TextOutW(200, 200, L"END pressed!");
			break;
		case VK_DELETE:
			pDC->TextOutW(200, 200, L"DELETE pressed!");
			break;
		case VK_LEFT:
			pDC->TextOutW(200, 200, L"LEFT pressed!");
			break;
		case VK_RIGHT:
			pDC->TextOutW(200, 200, L"RIGHT pressed!");
			break;
		case VK_UP:
			pDC->TextOutW(200, 200, L"UP pressed!");
			break;
		case VK_DOWN:
			pDC->TextOutW(200, 200, L"DOWN pressed!");
			break;
		case VK_NUMLOCK:
			pDC->TextOutW(200, 200, L"NUM LOCK pressed!");
			break;
		case VK_SCROLL:
			pDC->TextOutW(200, 200, L"SCROLL pressed!");
			break;
		case VK_LWIN:
			pDC->TextOutW(200, 200, L"LWIN pressed!");
			break;
		case VK_RWIN:
			pDC->TextOutW(200, 200, L"RWIN pressed!");
			break;
		case VK_ADD:
			pDC->TextOutW(200, 200, L"+ pressed!");
			break;
		case VK_SEPARATOR:
			pDC->TextOutW(200, 200, L"/ pressed!");
			break;
		case VK_SUBTRACT:
			pDC->TextOutW(200, 200, L"- pressed!");
			break;
		case VK_MULTIPLY:
			pDC->TextOutW(200, 200, L"* pressed!");
			break;
		case VK_DECIMAL:
			pDC->TextOutW(200, 200, L". pressed!");
			break;
		default:break;
		}
	}
	//释放设备上下文环境
	ReleaseDC(pDC);
	return CView::PreTranslateMessage(pMsg);
}


afx_msg LRESULT CMFCApplication1View::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
	//自定义消息,通过按键消息响应
	CString str;
	str.Format(L"Message Parameter is %d and %d", wParam, lParam);
	//获取hWnd所指窗口的客户区的设备环境
	CDC* pDC = GetDC();
	pDC->TextOutW(600, 200, str);
	//释放设备上下文环境
	ReleaseDC(pDC);
	return 0;
}
